# -*- coding: latin-1 -*-

#=========================================================================================
from Code.Constantes import *

import Code.VarGen as VarGen

import Code.Util as Util
import Code.Jugada as Jugada
import Code.Books as Books
import Code.XGestorMotor as XGestorMotor
import Code.Partida as Partida

import Code.Gestor as Gestor

#=========================================================================================
class GestorTorneo( Gestor.Gestor ) :

    #--------------------------------------------------------------------------------------------------------------------------------
    def inicio( self, torneo, liGames ) :

        self.tipoJuego = kJugMvM

        self.torneo = torneo
        self.liGames = liGames
        self.pantalla.ponActivarTutor( False )
        self.ponPiezasAbajo( True )
        self.mostrarIndicador( True )
        self.siTerminar = False
        self.pantalla.ponToolBar( ( k_cancelar, ) )
        self.colorJugando = True

        for gm in self.liGames :
            self.siguienteJuego(gm)
            if self.siTerminar :
                break

    #--------------------------------------------------------------------------------------------------------------------------------
    def siguienteJuego( self, gm ) :

        self.estado = kJugando

        self.gm = gm
        self.maxSegundos = self.gm.minutos()*60.0
        self.segundosJugada = self.gm.segundosJugada()

        rival = {}
        rival[True] = self.torneo.buscaHEngine(self.gm.hwhite())
        rival[False] = self.torneo.buscaHEngine(self.gm.hblack())

        self.tiempo = {}

        self.book = {}
        self.bookRR = {}

        self.xmotor = {}

        for color in (True,False) :

            rv = rival[color]
            self.xmotor[color] = XGestorMotor.GestorMotor( self.procesador, rv.configMotor() )
            self.xmotor[color].opciones( rv.time()*1000, rv.depth(), False )
            self.xmotor[color].ponGuiDispatch( self.guiDispatch, 1.0 )

            self.tiempo[color] = Util.Contador( self.maxSegundos )

            bk = rv.book()
            if bk == "*" :
                bk = VarGen.tbook
            elif bk == "-" :
                bk = None
            if bk :
                self.book[color] = Books.Libro( "P", bk, bk, True )
                self.book[color].polyglot()
            else :
                self.book[color] = None
            self.bookRR[color] = rv.bookRR()

        self.partida = Partida.Partida()
        self.pgn.partida = self.partida

        self.desactivaTodas( )
        self.ponPosicion( self.partida.ultPosicion )
        self.pgnRefresh( True )

        self.siPrimeraJugadaHecha = False
        tpBL = self.tiempo[True].etiqueta()
        tpNG = self.tiempo[False].etiqueta()
        bl = self.xmotor[True].nombre
        ng = self.xmotor[False].nombre
        self.pantalla.activaJuego( True, True, siAyudas=False)
        self.ponRotulo1( None )
        self.ponRotulo2( None )
        self.quitaAyudas()
        self.pantalla.ponDatosReloj( bl, tpBL, ng, tpNG )
        self.refresh()

        self.finPorTiempo = None
        while self.siguienteJugada() :
            pass

        self.xmotor[True].terminar()
        self.xmotor[False].terminar()
        self.pantalla.paraReloj( )

    #--------------------------------------------------------------------------------------------------------------------------------
    def guiDispatch( self, pv ) :
        if pv :
            self.ponFlechaSC( pv[:2], pv[2:4] )
            # QTUtil.refreshGUI()
        self.refresh()
        return not self.siTerminar

    #--------------------------------------------------------------------------------------------------------------------------------
    def compruebaFinal( self ) :
        if len(self.partida.liJugadas) < 4 :
            return False

        if self.finPorTiempo is not None:
            result = self.finPorTiempo

        else :
            jgUlt = self.partida.liJugadas[-1]
            result = None
            if self.partida.compruebaFinal() :
                if jgUlt.siJaqueMate :
                    result = 1 if jgUlt.posicionBase.siBlancas else 2
                else :
                    result = 0
            else :
                if not jgUlt.analisis :
                    return False
                mrm,pos = jgUlt.analisis
                rmUlt = mrm.liMultiPV[pos]
                jgAnt = self.partida.liJugadas[-2]
                if not jgAnt.analisis :
                    return False
                mrm,pos = jgAnt.analisis
                rmAnt = mrm.liMultiPV[pos]

                # Draw
                pUlt = rmUlt.puntosABS()
                pAnt = rmAnt.puntosABS()
                if self.partida.numJugadas() >= self.torneo.drawMinPly() :
                    dr = self.torneo.drawRange()
                    if abs(pUlt) <= dr and abs(pAnt) <= dr :
                        # rmTut = self.xtutor.analiza( self.partida.ultPosicion.fen() )
                        # pTut = rmTut.puntosABS()
                        # if abs(pTut) <= dr :
                        result = 0

                # Dif puntos
                if result is None :
                    rs = self.torneo.resign()
                    if pUlt >= rs and pAnt <= -rs :
                        # rmTut = self.xtutor.analiza( self.partida.ultPosicion.fen() )
                        # pTut = -rmTut.mejorMov().puntosABS()
                        # if pTut >= rs :
                        result = 1 if jgAnt.posicion.siBlancas else 2

            if result is None :
                return False

        self.gm.partida( self.partida )
        self.gm.result( result )
        self.torneo.grabar()

        return True

    #--------------------------------------------------------------------------------------------------------------------------------
    def siguienteJugada( self ) :

        if self.estado == kFinJuego :
            return False

        self.estado = kJugando

        siBlancas = self.partida.siBlancas()
        self.colorJugando = siBlancas

        if self.compruebaFinal() :
            return False

        self.ponIndicador( siBlancas )
        self.refresh()

        self.relojStart(siBlancas)

        siEncontrada = False
        analisis = None
        bk = self.book[siBlancas]
        if bk :
            siEncontrada, desde, hasta, coronacion = self.eligeJugadaBook(bk,self.bookRR[siBlancas])
            if not siEncontrada :
                self.book[siBlancas] = None

        if not siEncontrada :
            xrival = self.xmotor[siBlancas]
            tiempoBlancas = self.tiempo[True].tiempoPendiente
            tiempoNegras = self.tiempo[False].tiempoPendiente
            segundosJugada = xrival.motorTiempoJugada
            mrm = xrival.juegaTiempoTorneo(tiempoBlancas, tiempoNegras, segundosJugada )
            if mrm is None :
                return False
            rm = mrm.mejorMov()
            desde = rm.desde
            hasta = rm.hasta
            coronacion = rm.coronacion
            analisis = mrm, 0

        self.relojStop(siBlancas)

        siBien, mens, jg = Jugada.dameJugada( self.partida.ultPosicion, desde, hasta, coronacion )
        if analisis :
            jg.analisis = analisis
            jg.critica = "0"
        self.masJugada( jg )
        self.movimientosPiezas( jg.liMovs, True )

        return True
    #--------------------------------------------------------------------------------------------------------------------------------
    def ponReloj(self):

        if (not self.siPrimeraJugadaHecha) or (self.estado != kJugando) :
            return

        def mira( siBlancas ) :
            ot = self.tiempo[siBlancas]

            eti, eti2 = ot.etiquetaDif2()
            if eti :
                if siBlancas :
                    self.pantalla.ponRelojBlancas( eti, eti2 )
                else :
                    self.pantalla.ponRelojNegras( eti, eti2 )

            if ot.siAgotado() :
                self.finPorTiempo = 2 if siBlancas else 1
                return False

            return True

        mira( self.colorJugando )
        self.refresh()

    #--------------------------------------------------------------------------------------------------------------------------------
    def relojStart( self, siBlancas ) :
        if self.siPrimeraJugadaHecha :
            self.tiempo[ siBlancas ].iniciaMarcador()
            self.pantalla.iniciaReloj(self.ponReloj, transicion = 200 )

    #--------------------------------------------------------------------------------------------------------------------------------
    def relojStop( self, siBlancas ) :
        if self.siPrimeraJugadaHecha :
            self.tiempo[ siBlancas ].paraMarcador(self.segundosJugada)
            self.ponReloj()
            self.pantalla.paraReloj( )

    #--------------------------------------------------------------------------------------------------------------------------------
    def procesarAccion( self, clave ) :

        if clave == k_cancelar :
            self.siTerminar = True

    #--------------------------------------------------------------------------------------------------------------------------------
    def finalX( self ) :
        self.siTerminar = True
        return False

    #--------------------------------------------------------------------------------------------------------------------------------
    def eligeJugadaBook( self, book, tipo ) :
        fen = self.partida.fenUltimo()
        pv = book.eligeJugadaTipo( fen, tipo )
        if pv :
            return True, pv[:2], pv[2:4], pv[4:]
        else :
            return False, None, None, None

    #--------------------------------------------------------------------------------------------------------------------------------
    def masJugada( self, jg ) :

        if not self.siPrimeraJugadaHecha :
            self.siPrimeraJugadaHecha = True

        # Preguntamos al mono si hay movimiento
        if self.siTerminada() :
            jg.siJaqueMate = jg.siJaque
            jg.siAhogado = not jg.siJaque

        self.partida.liJugadas.append( jg )
        self.partida.ultPosicion = jg.posicion
        if self.partida.pendienteApertura :
            self.listaAperturasStd.asignaApertura( self.partida )

        resp = self.partida.si3repetidas()
        if resp :
            jg.siTablasRepeticion = True
            rotulo = ""
            for j in resp :
                rotulo += "%d,"%(j/2+1,)
            rotulo = rotulo.strip(",")
            self.rotuloTablasRepeticion = rotulo

        if self.partida.ultPosicion.movPeonCap >= 50 :
            jg.siTablas50 = True

        if self.partida.ultPosicion.siFaltaMaterial() :
            jg.siTablasFaltaMaterial = True

        self.ponFlechaSC( jg.desde, jg.hasta )

        self.pgnRefresh(self.partida.ultPosicion.siBlancas)

        self.refresh()

